﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BusinessMappingTest.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the  type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Business.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using AutoMapper;
    using Common;
    using Entities;
    using Mapping;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Defines the <seealso cref="Hisaab.Business.Tests.BusinessMappingTest"/> type.
    /// </summary>
    [TestClass]
    public class BusinessMappingTest
    {
        /// <summary>
        /// Initializes this instance.
        /// </summary>
        /// <param name="context">The context.</param>
        [ClassInitialize]
        public static void Initialize(TestContext context)
        {
            ObjectMapper.AddProfile(new BusinessMapping());
            Mapper.AssertConfigurationIsValid();
        }

        /// <summary>
        /// Mappings the should map account from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapAccountFromDataEntities()
        {
            var dataEntity = new Data.Entities.Account
                                 {
                                     AccountType = 1,
                                     Id = 3,
                                     Name = "Account Name"
                                 };
            var businessEntity = dataEntity.Map<Data.Entities.Account, Account>();

            Assert.AreEqual(dataEntity.Id, businessEntity.AccountId);
            Assert.AreEqual(dataEntity.AccountType, businessEntity.AccountType);
            Assert.AreEqual(dataEntity.Name, businessEntity.Name);
        }

        /// <summary>
        /// Mappings the should map account from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapAccountFromBusinessEntities()
        {
            var businessEntity = new Account
            {
                AccountType = 5,
                AccountId = 3,
                Name = "Account Name"
            };
            var dataEntity = businessEntity.Map<Account, Data.Entities.Account>();

            Assert.AreEqual(businessEntity.AccountId, dataEntity.Id);
            Assert.AreEqual(businessEntity.AccountType, dataEntity.AccountType);
            Assert.AreEqual(businessEntity.Name, dataEntity.Name);
        }

        /// <summary>
        /// Mappings the should map account type from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapAccountTypeFromDataEntities()
        {
            var dataEntity = new Data.Entities.AccountType
            {
                Id = 3,
                Name = "AccountType Name"
            };
            var businessEntity = dataEntity.Map<Data.Entities.AccountType, AccountType>();

            Assert.AreEqual(dataEntity.Id, businessEntity.Id);
            Assert.AreEqual(dataEntity.Name, businessEntity.Name);
        }

        /// <summary>
        /// Mappings the should map account type from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapAccountTypeFromBusinessEntities()
        {
            var businessEntity = new AccountType
            {
                Id = 3,
                Name = "Account Name"
            };
            var dataEntity = businessEntity.Map<AccountType, Data.Entities.AccountType>();

            Assert.AreEqual(businessEntity.Id, dataEntity.Id);
            Assert.AreEqual(businessEntity.Name, dataEntity.Name);
        }

        /// <summary>
        /// Mappings the should map tag from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTagFromDataEntities()
        {
            var dataEntity = new Data.Entities.Tag
            {
                Id = 3,
                Name = "Tag Name"
            };
            var businessEntity = dataEntity.Map<Data.Entities.Tag, Tag>();

            Assert.AreEqual(dataEntity.Id, businessEntity.TagId);
            Assert.AreEqual(dataEntity.Name, businessEntity.Name);
        }

        /// <summary>
        /// Mappings the should map tag from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTagFromBusinessEntities()
        {
            var businessEntity = new Tag
            {
                TagId = 3,
                Name = "Account Name"
            };
            var dataEntity = businessEntity.Map<Tag, Data.Entities.Tag>();

            Assert.AreEqual(businessEntity.TagId, dataEntity.Id);
            Assert.AreEqual(businessEntity.Name, dataEntity.Name);
        }

        /// <summary>
        /// Mappings the should map transaction from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTransactionFromDataEntitiesWithPositiveAmount()
        {
            var dataEntity = new Data.Entities.Transaction
            {
                Id = 3,
                Title = "Transaction 1",
                Details = "bought some stuff",
                Account = 45,
                Amount = 4.56M,
                Date = DateTime.Now,
                Tags = new List<Data.Entities.Tag>
                    {
                        new Data.Entities.Tag { Id  = 1, Name = "Tag1" },
                        new Data.Entities.Tag { Id  = 2, Name = "Tag2" }
                    }
            };
            var businessEntity = dataEntity.Map<Data.Entities.Transaction, Transaction>();

            Assert.AreEqual(dataEntity.Id, businessEntity.TransactionId);
            Assert.AreEqual(dataEntity.Title, businessEntity.Title);
            Assert.AreEqual(dataEntity.Details, businessEntity.Details);
            Assert.AreEqual(dataEntity.Account, businessEntity.Account);
            Assert.AreEqual(dataEntity.Date, businessEntity.Date);
            Assert.AreEqual(false, businessEntity.IsTransferTransaction);
            Assert.AreEqual(TransactionTypes.Income, businessEntity.TransactionType);
            Assert.AreEqual(dataEntity.Tags.Count, businessEntity.Tags.Count());
            Assert.AreEqual(dataEntity.Tags.ElementAt(0).Id, businessEntity.Tags.ElementAt(0).TagId);
            Assert.AreEqual(dataEntity.Tags.ElementAt(0).Name, businessEntity.Tags.ElementAt(0).Name);
            Assert.AreEqual(dataEntity.Tags.ElementAt(1).Id, businessEntity.Tags.ElementAt(1).TagId);
            Assert.AreEqual(dataEntity.Tags.ElementAt(1).Name, businessEntity.Tags.ElementAt(1).Name);
        }

        /// <summary>
        /// Mappings the should map transaction from data entities with negative amount.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTransactionFromDataEntitiesWithNegativeAmount()
        {
            var dataEntity = new Data.Entities.Transaction
            {
                Id = 3,
                Title = "Transaction 1",
                Details = "bought some stuff",
                Account = 45,
                Amount = -4.56M,
                RelatedTransactionId = 3,
                Date = DateTime.Now,
                Tags = new List<Data.Entities.Tag>
                    {
                        new Data.Entities.Tag { Id  = 1, Name = "Tag1" },
                        new Data.Entities.Tag { Id  = 2, Name = "Tag2" }
                    }
            };
            var businessEntity = dataEntity.Map<Data.Entities.Transaction, Transaction>();

            Assert.AreEqual(dataEntity.Id, businessEntity.TransactionId);
            Assert.AreEqual(dataEntity.Title, businessEntity.Title);
            Assert.AreEqual(dataEntity.Details, businessEntity.Details);
            Assert.AreEqual(dataEntity.Account, businessEntity.Account);
            Assert.AreEqual(Math.Abs(dataEntity.Amount), businessEntity.Amount);
            Assert.AreEqual(dataEntity.Date, businessEntity.Date);
            Assert.AreEqual(true, businessEntity.IsTransferTransaction);
            Assert.AreEqual(TransactionTypes.Expanse, businessEntity.TransactionType);
            Assert.AreEqual(dataEntity.Tags.Count, businessEntity.Tags.Count());
            Assert.AreEqual(dataEntity.Tags.ElementAt(0).Id, businessEntity.Tags.ElementAt(0).TagId);
            Assert.AreEqual(dataEntity.Tags.ElementAt(0).Name, businessEntity.Tags.ElementAt(0).Name);
            Assert.AreEqual(dataEntity.Tags.ElementAt(1).Id, businessEntity.Tags.ElementAt(1).TagId);
            Assert.AreEqual(dataEntity.Tags.ElementAt(1).Name, businessEntity.Tags.ElementAt(1).Name);
        }

        /// <summary>
        /// Mappings the should map transaction from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTransactionFromBusinessEntitiesWithIncome()
        {
            var businessEntity = new Transaction
                                     {
                                         TransactionId = 3,
                                         Title = "Transaction 1",
                                         Details = "bought some stuff",
                                         Account = 45,
                                         Amount = 4.56M,
                                         Date = DateTime.Now,
                                         TransactionType = TransactionTypes.Income,
                                         Tags = new List<Tag>
                                                    {
                                                        new Tag { TagId  = 1, Name = "Tag1" },
                                                        new Tag { TagId  = 2, Name = "Tag2" }
                                                    }
                                     };
            var dataEntity = businessEntity.Map<Transaction, Data.Entities.Transaction>();

            Assert.AreEqual(businessEntity.TransactionId, dataEntity.Id);
            Assert.AreEqual(businessEntity.Title, dataEntity.Title);
            Assert.AreEqual(businessEntity.Details, dataEntity.Details);
            Assert.AreEqual(businessEntity.Account, dataEntity.Account);
            Assert.AreEqual(businessEntity.Amount, dataEntity.Amount);
            Assert.AreEqual(businessEntity.Date, dataEntity.Date);
            Assert.AreEqual(businessEntity.Tags.Count(), dataEntity.Tags.Count);
            Assert.AreEqual(businessEntity.Tags.ElementAt(0).TagId, dataEntity.Tags.ElementAt(0).Id);
            Assert.AreEqual(businessEntity.Tags.ElementAt(0).Name, dataEntity.Tags.ElementAt(0).Name);
            Assert.AreEqual(businessEntity.Tags.ElementAt(1).TagId, dataEntity.Tags.ElementAt(1).Id);
            Assert.AreEqual(businessEntity.Tags.ElementAt(1).Name, dataEntity.Tags.ElementAt(1).Name);
        }

        /// <summary>
        /// Mappings the should map transaction from business entities with negative amount.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapTransactionFromBusinessEntitiesWithExpanse()
        {
            var businessEntity = new Transaction
            {
                TransactionId = 3,
                Title = "Transaction 1",
                Details = "bought some stuff",
                Account = 45,
                Amount = 4.56M,
                Date = DateTime.Now,
                TransactionType = TransactionTypes.Expanse,
                Tags = new List<Tag>
                                                    {
                                                        new Tag { TagId  = 1, Name = "Tag1" },
                                                        new Tag { TagId  = 2, Name = "Tag2" }
                                                    }
            };
            var dataEntity = businessEntity.Map<Transaction, Data.Entities.Transaction>();

            Assert.AreEqual(businessEntity.TransactionId, dataEntity.Id);
            Assert.AreEqual(businessEntity.Title, dataEntity.Title);
            Assert.AreEqual(businessEntity.Details, dataEntity.Details);
            Assert.AreEqual(businessEntity.Account, dataEntity.Account);
            Assert.AreEqual(businessEntity.Amount, -dataEntity.Amount);
            Assert.AreEqual(businessEntity.Date, dataEntity.Date);
            Assert.AreEqual(businessEntity.Tags.Count(), dataEntity.Tags.Count);
            Assert.AreEqual(businessEntity.Tags.ElementAt(0).TagId, dataEntity.Tags.ElementAt(0).Id);
            Assert.AreEqual(businessEntity.Tags.ElementAt(0).Name, dataEntity.Tags.ElementAt(0).Name);
            Assert.AreEqual(businessEntity.Tags.ElementAt(1).TagId, dataEntity.Tags.ElementAt(1).Id);
            Assert.AreEqual(businessEntity.Tags.ElementAt(1).Name, dataEntity.Tags.ElementAt(1).Name);
        }

        /// <summary>
        /// Mappings the should map vehicle transaction from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapVehicleTransactionFromDataEntities()
        {
            var dataEntity = new Data.Entities.VehicleTransaction
            {
                Id = 3,
                Fill = 4.56M,
                Milage = 100987,
                Oil = 34.55M,
                Service = 34.45M,
                Tires = 103.44M,
                VehicleId = 344,
                TransactionId = 43
            };
            var businessEntity = dataEntity.Map<Data.Entities.VehicleTransaction, VehicleTransaction>();

            Assert.AreEqual(dataEntity.Id, businessEntity.Id);
            Assert.AreEqual(dataEntity.Fill, businessEntity.Fill);
            Assert.AreEqual(dataEntity.Fuel, businessEntity.Fuel);
            Assert.AreEqual(dataEntity.Milage, businessEntity.Milage);
            Assert.AreEqual(dataEntity.Oil, businessEntity.Oil);
            Assert.AreEqual(dataEntity.Service, businessEntity.Service);
            Assert.AreEqual(dataEntity.Tires, businessEntity.Tires);
            Assert.AreEqual(dataEntity.VehicleId, businessEntity.VehicleId);
            Assert.AreEqual(dataEntity.TransactionId, businessEntity.TransactionId);
            Assert.AreEqual(0, businessEntity.Account);
        }

        /// <summary>
        /// Mappings the should map vehicle transaction from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapVehicleTransactionFromBusinessEntities()
        {
            var businessEntity = new VehicleTransaction
            {
                Id = 3,
                Fill = 4.56M,
                Milage = 100987,
                Oil = 34.55M,
                Service = 34.45M,
                Tires = 103.44M,
                VehicleId = 344,
                TransactionId = 43
            };
            var dataEntity = businessEntity.Map<VehicleTransaction, Data.Entities.VehicleTransaction>();

            Assert.AreEqual(businessEntity.Id, dataEntity.Id);
            Assert.AreEqual(businessEntity.Fill, dataEntity.Fill);
            Assert.AreEqual(businessEntity.Fuel, dataEntity.Fuel);
            Assert.AreEqual(businessEntity.Milage, dataEntity.Milage);
            Assert.AreEqual(businessEntity.Oil, dataEntity.Oil);
            Assert.AreEqual(businessEntity.Service, dataEntity.Service);
            Assert.AreEqual(businessEntity.Tires, dataEntity.Tires);
            Assert.AreEqual(businessEntity.VehicleId, dataEntity.VehicleId);
            Assert.AreEqual(businessEntity.TransactionId, dataEntity.TransactionId);
        }

        /// <summary>
        /// Mappings the should map user from data entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapUserFromDataEntities()
        {
            var dataEntity = new Data.Entities.User
            {
                Id = 3,
                Name = "johndoe",
                Password = "123454"
            };
            var businessEntity = dataEntity.Map<Data.Entities.User, User>();

            Assert.AreEqual(dataEntity.Id, businessEntity.UserId);
            Assert.AreEqual(dataEntity.Name, businessEntity.Name);
        }

        /// <summary>
        /// Mappings the should map user from business entities.
        /// </summary>
        [TestMethod]
        public void MappingShouldMapUserFromBusinessEntities()
        {
            var businessEntity = new User
            {
                UserId = 3,
                Name = "JaneDoe",
            };
            var dataEntity = businessEntity.Map<User, Data.Entities.User>();

            Assert.AreEqual(businessEntity.UserId, dataEntity.Id);
            Assert.AreEqual(businessEntity.Name, dataEntity.Name);
        }
    }
}